/* eslint-disable @typescript-eslint/no-misused-promises */
// Copyright 2025 祝灵福
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { HttpAdapterHost, NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'

import 'winston-daily-rotate-file' //全部导入
import { setupApp } from './setup'
// import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'
import { Logger, ValidationPipe } from '@nestjs/common'
import { NestExpressApplication } from '@nestjs/platform-express'
import { getServicerConfig } from '../ormconfig'
// import { AllExceptionFilter } from './filters/all-exception.filter'
// import { HttpExceptionFilter } from './filters/http-exception.filter'
// import { SerializeInterceptor } from './interceptors/serialize/serialize.interceptor'

//使用异步函数是因为启动过程可能涉及一些需要等待的操作（比如初始化服务或连接数据库）。
async function bootstrap() {
  // nest-winston
  // createLogger of Winston
  //创建一个日志记录器实例。
  // const instance = createLogger({
  //   // options of Winston
  //   transports: [
  //     new winston.transports.Console({
  //       level: 'info',
  //       format: winston.format.combine(winston.format.timestamp(), utilities.format.nestLike())
  //     }),
  //     //还可以配置events-archive rodate
  //     new winston.transports.DailyRotateFile({
  //       dirname: 'logs', //指定目录，生产的时候可以指定绝对目录
  //       level: 'warn', //设置日志记录的级别为 info,记录 info、warn、error 级别的,但不会记录 debug 或 trace 级别的日志
  //       filename: 'application-%DATE%.log', //文件名，%DATE%占位符用于动态地插入实际的日期，可以改为info-%DATE%.log方便分辨
  //       datePattern: 'YYYY-MM-DD-HH', //定义日期格式化的模式，用于文件名中插入日期的部分
  //       zippedArchive: true, //表示是否启用日志文件压缩。
  //       maxSize: '20m', //指定每个日志文件的最大大小，当文件大小超过此限制时，会自动滚动到新文件
  //       maxFiles: '14d', //指定日志文件保留的最大时间。这里超过14天自动删除
  //       format: winston.format.combine(winston.format.timestamp(), winston.format.simple())
  //     }),
  //     new winston.transports.DailyRotateFile({
  //       dirname: 'logs', //指定目录，生产的时候可以指定绝对目录
  //       level: 'info', //设置日志记录的级别为 info,记录 info、warn、error 级别的,但不会记录 debug 或 trace 级别的日志
  //       filename: 'info-%DATE%.log', //文件名，%DATE%占位符用于动态地插入实际的日期，可以改为info-%DATE%.log方便分辨
  //       datePattern: 'YYYY-MM-DD-HH', //定义日期格式化的模式，用于文件名中插入日期的部分
  //       zippedArchive: true, //表示是否启用日志文件压缩。
  //       maxSize: '20m', //指定每个日志文件的最大大小，当文件大小超过此限制时，会自动滚动到新文件
  //       maxFiles: '14d', //指定日志文件保留的最大时间。这里超过14天自动删除
  //       format: winston.format.combine(winston.format.timestamp(), winston.format.simple())
  //     })
  //   ]
  // })
  // 原配置：logger
  const logger = new Logger(bootstrap.name) //类名.name: 打印时会显示哪个类名
  //在await等待过程中，NestJS 会根据 AppModule 初始化所有配置、依赖等。
  //静态方法，用于创建一个新的 NestJS 应用实例。AppModule 是应用的根模块，它包含了所有其他模块的引导和依赖关系。
  // const logger = WinstonModule.createLogger({ instance })
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    // 关闭整个nestjs内置的logger日志，默认打开
    // logger: false
    // 选择性打印日志等级
    // logger: ['error', 'warn']
    // logger: logger
    // 允许跨域
    cors: true
  })
  app.set('trust proxy', 'loopback')
  // 将管道那些封装成了setupApp
  setupApp(app, logger)
  // app.listen() 的作用是启动应用的 HTTP 服务器，开始监听指定的端口并处理请求
  // process.env.PORT：这是环境变量中存储的端口。如果环境中没有指定端口（即 process.env.PORT 为 undefined），就会使用 3000 作为默认端口。
  const config = getServicerConfig() //ormconfig.ts提供的
  const port = typeof config['APP_POST'] === 'string' ? parseInt(config['APP_POST']) : 3000
  // await app.listen(process.env.PORT ?? port)
  await app.listen(port)
  console.log('hello nestjs1')
  // logger.log(`app打印在：${port}`) //绿色
  // logger.warn(`app打印在：${port}`) //黄色
  // logger.error(`app打印在：${port}`) //红色

  // 热模块更换
  if (module.hot) {
    module.hot.accept()
    module.hot.dispose(() => app.close())
  }
}
bootstrap()
